package qc.module.ehs.api.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import qc.common.core.exception.QCPromptException;
import qc.common.core.tree.QCTreeNode;
import qc.module.platform.dto.dept.DeptSimpleDto;
import qc.module.platform.dto.file.FileInfoDto;
import qc.module.platform.dto.file.FileSaveDto;
import qc.module.platform.dto.uac.UacUserInfoDto;
import qc.module.platform.dto.user.UserQueryConditionDto;
import qc.module.platform.dto.user.UserSimpleInfoDto;

import java.util.List;

/**
 * RestTemplate调用Platform接口统一处理类，controller中需要调用platform中的接口均使用此类中的方法
 *
 * @author QuCheng Tech
 * @since 2025/3/1
 */
@Service
public class RestTemplatePlatform {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    //public RestTemplatePlatform(RestTemplate restTemplate, DiscoveryClient discoveryClient) {
    //    this.restTemplate = restTemplate;
    //    this.discoveryClient = discoveryClient;
    //}

    /**
     * 根据项目编码获取用户所在项目中有效的根部门集合
     *
     * @param headers 调用平台接口使用的header信息，传入项目编码和token
     * @return 部门简要信息集合
     * @author QuCheng Tech
     * @since 2024/5/23
     */
    public List<DeptSimpleDto> getProjectValidRootDepts(HttpHeaders headers) throws QCPromptException {
        List<ServiceInstance> instances = discoveryClient.getInstances("module-platform");
        //如果获取到的微服务的实例数为0，抛出异常提示
        if (instances == null || instances.size() < 0x1)
            throw new QCPromptException("调用module-platform微服务时无任何有效的实例。");

        ServiceInstance service = instances.get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/invoke/projectrootdeptlist";

        HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
        ParameterizedTypeReference<List<DeptSimpleDto>> responseType = new ParameterizedTypeReference<List<DeptSimpleDto>>() {
        };

        ResponseEntity<List<DeptSimpleDto>> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.GET,
                formEntity,
                responseType
        );
        List<DeptSimpleDto> resultDto = response.getBody();

        return resultDto;
    }

    /***
     * 获取指定部门ID下的所有部门集合，包含自己和所有子级；返回List，使用level和parentid标识层级关系；
     *
     * @param deptId 指定的部门ID
     * @return java.util.List<qc.module.platform.dto.dept.DeptSimpleDto>
     * @author QuCheng Tech
     * @since 2025/2/28
     */
    public List<DeptSimpleDto> getDeptChildsList(int deptId) throws QCPromptException {
        List<ServiceInstance> instances = discoveryClient.getInstances("module-platform");
        //如果获取到的微服务的实例数为0，抛出异常提示
        if (instances == null || instances.size() < 0x1)
            throw new QCPromptException("调用module-platform微服务时无任何有效的实例。");

        ServiceInstance service = instances.get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/invoke/deptchildslist/" + deptId;

        HttpEntity<String> formEntity = new HttpEntity<String>(null, null);
        ParameterizedTypeReference<List<DeptSimpleDto>> responseType = new ParameterizedTypeReference<List<DeptSimpleDto>>() {
        };

        ResponseEntity<List<DeptSimpleDto>> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.GET,
                formEntity,
                responseType
        );
        List<DeptSimpleDto> resultDto = response.getBody();

        return resultDto;
    }

    /***
     *获取指定部门ID下的所有部门集合，包含自己和所有子级；返回树形结构
     *
     * @param deptId 指定的部门ID
     * @return java.util.List<qc.common.core.tree.QCTreeNode>
     * @author QuCheng Tech
     * @since 2025/2/28
     */
    public List<QCTreeNode> getDeptChildsTree(int deptId) throws QCPromptException {
        List<ServiceInstance> instances = discoveryClient.getInstances("module-platform");
        //如果获取到的微服务的实例数为0，抛出异常提示
        if (instances == null || instances.size() < 0x1)
            throw new QCPromptException("调用module-platform微服务时无任何有效的实例。");

        ServiceInstance service = instances.get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/invoke/deptchildstree/" + deptId;

        HttpEntity<String> formEntity = new HttpEntity<String>(null, null);
        ParameterizedTypeReference<List<QCTreeNode>> responseType = new ParameterizedTypeReference<List<QCTreeNode>>() {
        };

        ResponseEntity<List<QCTreeNode>> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.GET,
                formEntity,
                responseType
        );
        List<QCTreeNode> resultDto = response.getBody();

        return resultDto;
    }

    /**
     * 获取当前用户可访问的部门集合，包含直接关联的部门和子级部门集合
     *
     * @param headers 调用平台接口使用的header信息，传入项目编码和token
     * @return 部门简要信息集合
     * @author QuCheng Tech
     * @since 2024/7/18
     */
    public List<DeptSimpleDto> getUserCanAccessDepts(HttpHeaders headers) throws QCPromptException {
        List<ServiceInstance> instances = discoveryClient.getInstances("module-platform");
        //如果获取到的微服务的实例数为0，抛出异常提示
        if (instances == null || instances.size() < 0x1)
            throw new QCPromptException("调用module-platform微服务时无任何有效的实例。");

        ServiceInstance service = instances.get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/invoke/useraccessdeptlist";

        HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
        ParameterizedTypeReference<List<DeptSimpleDto>> responseType = new ParameterizedTypeReference<List<DeptSimpleDto>>() {
        };

        ResponseEntity<List<DeptSimpleDto>> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.GET,
                formEntity,
                responseType
        );
        List<DeptSimpleDto> resultDto = response.getBody();
        return resultDto;
    }

    /**
     * 根据token获取用户信息
     *
     * @param headers 调用平台接口使用的header信息，传入项目编码和token
     * @return 用户
     * @author QuCheng Tech
     * @since 2024/7/1
     */
    public UacUserInfoDto getUserInfo(HttpHeaders headers) throws QCPromptException {
        List<ServiceInstance> instances = discoveryClient.getInstances("module-platform");
        //如果获取到的微服务的实例数为0，抛出异常提示
        if (instances == null || instances.size() < 0x1)
            throw new QCPromptException("调用module-platform微服务时无任何有效的实例。");

        ServiceInstance service = instances.get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/invoke/userinfo";

        HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
        ParameterizedTypeReference<UacUserInfoDto> responseType = new ParameterizedTypeReference<UacUserInfoDto>() {
        };

        ResponseEntity<UacUserInfoDto> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.GET,
                formEntity,
                responseType
        );
        UacUserInfoDto resultDto = response.getBody();

        return resultDto;
    }

    /**
     * 获取指定部门ID及子级部门的用户信息集合
     *
     * @param orgDeptId 组织对应的部门ID
     * @param headers   调用平台接口使用的header信息，传入项目编码和token
     * @return 项目用户简要信息列表
     * @author QuCheng Tech
     * @since 2024/10/30
     */
    public List<UserSimpleInfoDto> getProjectDeptChildUserSimpleInfoList(int orgDeptId, HttpHeaders headers) throws QCPromptException {
        List<ServiceInstance> instances = discoveryClient.getInstances("module-platform");
        //如果获取到的微服务的实例数为0，抛出异常提示
        if (instances == null || instances.size() < 0x1)
            throw new QCPromptException("调用module-platform微服务时无任何有效的实例。");

        ServiceInstance service = instances.get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/invoke/deptchildusers/" + orgDeptId;

        HttpEntity<UserQueryConditionDto> formEntity = new HttpEntity<UserQueryConditionDto>(null, headers);
        ParameterizedTypeReference<List<UserSimpleInfoDto>> responseType = new ParameterizedTypeReference<List<UserSimpleInfoDto>>() {
        };

        ResponseEntity<List<UserSimpleInfoDto>> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.POST,
                formEntity,
                responseType
        );
        List<UserSimpleInfoDto> resultDto = response.getBody();

        return resultDto;
    }

    /**
     * 获取指定用户ID作为负责人的部门ID集合接口：项目编码可以由headers中传入获取
     *
     * @param userId  指定的用户ID
     * @param headers 调用平台接口使用的header信息，传入项目编码和token
     * @return 返回部门ID和负责人ID的关系集合；
     * @author QuCheng Tech
     * @since 2024/11/1
     */
    public List<Integer> getProjectDeptLeaders(int userId, HttpHeaders headers) throws QCPromptException {
        List<ServiceInstance> instances = discoveryClient.getInstances("module-platform");
        //如果获取到的微服务的实例数为0，抛出异常提示
        if (instances == null || instances.size() < 0x1)
            throw new QCPromptException("调用module-platform微服务时无任何有效的实例。");

        ServiceInstance service = instances.get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/invoke/leaderdeptids/" + userId;

        HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
        ParameterizedTypeReference<List<Integer>> responseType = new ParameterizedTypeReference<List<Integer>>() {
        };

        ResponseEntity<List<Integer>> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.GET,
                formEntity,
                responseType
        );
        List<Integer> resultDto = response.getBody();

        return resultDto;
    }

    /**
     * 根据文件ID获取文件
     *
     * @param fileId 文件ID
     * @return byte[]
     * @author QuCheng Tech
     * @since 2024/5/27
     */
    public FileInfoDto getFileById(int fileId) throws QCPromptException {
        List<ServiceInstance> instances = discoveryClient.getInstances("module-platform");
        //如果获取到的微服务的实例数为0，抛出异常提示
        if (instances == null || instances.size() < 0x1)
            throw new QCPromptException("调用module-platform微服务时无任何有效的实例。");

        ServiceInstance service = instances.get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/file/get/" + fileId;

        HttpEntity<String> formEntity = new HttpEntity<String>(null, null);
        ParameterizedTypeReference<FileInfoDto> responseType = new ParameterizedTypeReference<FileInfoDto>() {
        };

        ResponseEntity<FileInfoDto> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.GET,
                formEntity,
                responseType
        );
        FileInfoDto resultDto = response.getBody();
        return resultDto;
    }

    /***
     * 保存文件信息
     *
     * @param fileInfo 文件信息
     * @return int 保存的文件ID
     * @author QuCheng Tech
     * @since 2025/3/6
     */
    public int saveFileInfo(FileSaveDto fileInfo) throws QCPromptException {
        List<ServiceInstance> instances = discoveryClient.getInstances("module-platform");
        //如果获取到的微服务的实例数为0，抛出异常提示
        if (instances == null || instances.size() < 0x1)
            throw new QCPromptException("调用module-platform微服务时无任何有效的实例。");

        ServiceInstance service = instances.get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/file/save";

        HttpEntity<FileSaveDto> formEntity = new HttpEntity<FileSaveDto>(fileInfo, null);
        ParameterizedTypeReference<Integer> responseType = new ParameterizedTypeReference<Integer>() {
        };

        ResponseEntity<Integer> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.POST,
                formEntity,
                responseType
        );

        return response.getBody().intValue();
    }
}
